package client;


import java.io.IOException;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.Socket;

import java.rmi.Naming;
import java.rmi.NotBoundException;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

import java.util.Scanner;
import common.ClientInterface;

import common.ServerInterface;
import common.SocketPerServerInterface;

public class Client extends UnicastRemoteObject implements ClientInterface,Serializable{
	
	private static final long serialVersionUID = 1L;
	private Visualizzazione visual;
	private ServerInterface serverInt;//tipo connessione, e in diretta contiene il server usato e quindi la partita
	private boolean loggato= false;
	private boolean creato=false;
	private boolean inPartita=false;
	private boolean esci=false;
	private String token=null;
	private String username=null;
	private Socket socket;
	private boolean rmi=false;
	
	public Client(char paramInterface,char paramConn,char paramMappa) throws RemoteException{
				
		//if(paramInterface=='t')
			//visual=new Testuale();
		//else
			visual=new Grafica(this);
					
		if(paramConn=='d'){
			//tolgo la diretta per poter dividere i package
			//Server server= new Server(paramMappa,this);
			//serverInt= server.getPartita();
		}	
	}
	
	public Client() throws RemoteException{
		
	}
	
	public static void main(String[] args) throws RemoteException {
		String schermata=null;
		char paramConn,paramMappa,paramInterface;
		
		//------------------SCELTA INTERFACCIA,CONNESSIONE,MAPPA------
		System.out.println("VIDEOGIOCO ISOLA DEI DINOSAURI - CLIENT");
		paramConn=sceltaConnessione();
		if(paramConn=='d')
			paramMappa=sceltaMappa();
		else
			paramMappa='z';
		//paramInterface=sceltaInterfaccia();
		paramInterface='g';//scelgo sempre l'interfaccia grafica
		//------------------------------------------------------------
		
		Client client = new Client(paramInterface,paramConn,paramMappa);
		
		//------------------SCHERMATE---------------------------------
		boolean connessioneOK=false;
		while(client.esci==false){
			if(client.loggato==false ){
				if(paramConn=='s'){
					while(connessioneOK==false){
						try {
							startConnessioneSocket(client);
							connessioneOK=true;
						}catch (IOException e){
							System.out.println("Indirizzo IP non corretto!");
						}
					}	
				}
				else if(paramConn=='r'){
					while(connessioneOK==false){
						try {
							startConnessioneRMI(client);
							connessioneOK=true;
						} catch (MalformedURLException e) {
							System.out.println("Indirizzo IP non corretto!");
						} catch (NotBoundException e) {
							System.out.println("Indirizzo IP non corretto!");
						}
					}
				}
				client.visual.primaSchermata(client);
			}
			if(client.loggato==true&&client.inPartita==false){
				client.visual.secondaSchermata(client);
			}
			if(client.loggato==true&&client.inPartita==true){
				client.visual.terzaSchermata(client);
			}
		}
		//-----------------------------------------------------------
		
		System.exit(0);
	
	}

	private static void startConnessioneSocket(Client client) throws IOException {
		//String host="localhost";
		//String host="192.168.66.66";
		String host= sceltaIP();
		int port=8888;
		System.out.println("Connecting to " + host+ ":" + port+ " ...");
		client.socket= new Socket(host, port);
		System.out.println("Connected");
		client.serverInt= new SocketPerServerInterface(client);
		ClientThreadAscoltaRisposta t= new ClientThreadAscoltaRisposta(client.socket,((SocketPerServerInterface) client.serverInt).getBufferedReader(),client);
		((SocketPerServerInterface)client.serverInt).setT(t);
		t.start();
	}
	
	private static void startConnessioneRMI(Client client) throws MalformedURLException,RemoteException,NotBoundException{
		client.rmi=true;
		String host= sceltaIP();
		ServerInterface RMIserver = (ServerInterface)Naming.lookup("rmi://"+host+"/RMIserver:1999");
		System.out.println("Il client ha inizializzato la connessione RMI.");
		client.serverInt=RMIserver;
	}

	public Socket getSocket() {
		return socket;
	}

	public void setSocket(Socket socket) {
		this.socket = socket;
	}

	public Visualizzazione getVisual() {
		return visual;
	}

	public void setVisual(Visualizzazione visual) {
		this.visual = visual;
	}

	public ServerInterface getServerInt() {
		return serverInt;
	}

	public void setServerInt(ServerInterface serverInt) {
		this.serverInt = serverInt;
	}
	
	public boolean isLoggato() {
		return loggato;
	}

	public void setLoggato(boolean loggato) {
		this.loggato = loggato;
	}
	
	public boolean isCreato() {
		return creato;
	}

	public void setCreato(boolean creato) {
		this.creato = creato;
	}

	public boolean isEsci() {
		return esci;
	}

	public void setEsci(boolean esci) {
		this.esci = esci;
	}
	
	public String getToken() {
		return token;
	}

	public void setToken(String token) {
		this.token = token;
	}
	
	public boolean isInPartita() {
		return inPartita;
	}

	public void setInPartita(boolean inPartita) {
		this.inPartita = inPartita;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}
	
	public boolean isRmi() {
		return rmi;
	}

	public void setRmi(boolean rmi) {
		this.rmi = rmi;
	}

	private static char sceltaConnessione(){
		
		String sceltaGiocatore;
		String sceltaConn;
		char paramConn;
		
		Scanner in= new Scanner(System.in);
		
		boolean sceltaValida;
		/*do{
			System.out.print("Scegli giocatore singolo (s) o multiplayer (m): ");
			sceltaGiocatore=in.next();
			
			if( !(sceltaGiocatore.equals("s")) && !(sceltaGiocatore.equals("m")) ){
				System.out.println("Scelta non valida");
				sceltaValida=false;
			}else{
				sceltaValida=true;
			}
		}while( sceltaValida==false );*/
		sceltaGiocatore="m";
		if(sceltaGiocatore.equals("s")){
			paramConn='d';//giocatore singolo implica connessione diretta
		}
		else{
			
			do{
				System.out.print("Scegli tipologia di connessione Socket (s) o RMI (r): ");
				sceltaConn=in.next();
				
				if( !(sceltaConn.equals("s")) && !(sceltaConn.equals("r")) ){
					System.out.println("Scelta non valida");
					sceltaValida=false;
				}else{
					sceltaValida=true;
				}
			}while( sceltaValida==false );
			
			if(sceltaConn.equals("s")){
				paramConn='s';
			}
			else {
				paramConn='r';
			}
		}
		return paramConn;
	}
	
	private static char sceltaInterfaccia(){
		String sceltaInterfaccia;
		char paramInterface;
		Scanner in= new Scanner(System.in);
		boolean sceltaValida;
		
		do{
			System.out.print("Scegli tra interfaccia testuale(t) o grafica(g): ");
			sceltaInterfaccia=in.next();
			
			if( !(sceltaInterfaccia.equals("t")) && !(sceltaInterfaccia.equals("g")) ){
				System.out.println("Scelta non valida");
				sceltaValida=false;
			}else{
				sceltaValida=true;
			}
		}while( sceltaValida==false );
		
		if(sceltaInterfaccia.equals("g")){
			paramInterface='g';
		}
		else
			paramInterface='t';
		
		return paramInterface;
		
	}
	
	private static char sceltaMappa(){
		Scanner in= new Scanner(System.in);
		boolean sceltaValida=true;
		String sceltaMappa=null;
		do{
			System.out.print("Scegli se utilizzare mappa di default (d) o una mappa casuale (c): ");
			sceltaMappa=in.next();
			
			if( !(sceltaMappa.equals("d")) && !(sceltaMappa.equals("c")) ){
				System.out.println("Scelta non valida");
				sceltaValida=false;
			}else{
				sceltaValida=true;
			}
		}while( sceltaValida==false );
		char m= sceltaMappa.toCharArray()[0];
		return m;
	}
	
	private static String sceltaIP(){
		Scanner in= new Scanner(System.in);
		String sceltaIP="";
		System.out.print("Digita l'indirizzo IP del server: ");
		sceltaIP=in.next();
		if(sceltaIP.equals("l"))
			sceltaIP="localhost";
		return sceltaIP;
	}
	
	@Override
	public void ok(){
		visual.displayOk();
	}
	
	@Override
	public void ok(String s){
		visual.displayOk(s);
	}
	
	@Override
	public void no(String errore){
		visual.displayNo(errore);
	}
	
	@Override
	public void listaGiocatori(String[] giocatori){
		visual.displayListaGiocatori(giocatori);
	}
	
	@Override
	public void classifica(String[] punteggi){
		visual.displayClassifica(punteggi);
	}
	
	@Override
	public void mappaGenerale(String[] mappa){
		visual.displayMappaGenerale(mappa);
	}
	
	@Override
	public void listaDinosauri(String[] dinosauri){
		visual.displayListaDinosauri(dinosauri);
	}
	
	@Override
	public void vistaLocale(String[] vista){
		visual.displayVistaLocale(vista);
	}
	
	@Override
	public void statoDinosauro(String dinosauro){
		visual.displayStatoDinosauro(dinosauro);
	}
	
	@Override
	public void cambioTurno(String username) {
		ThreadDisplayCambioTurno t= new ThreadDisplayCambioTurno(visual,username);
		t.start();
	}
	
}
